//
// @Auther: by wujehy 
// @Email:wujehy@qq.com
// @Data:2020/9/17
// @Time:5:33 下午
//
//
#include <iostream>
#include <memory>
#include "BaseClientMod.h"
#include "your_protocol.h"
#include "NetworkProtocol.h"

class EchoClientMod : public GeeJoan::BaseClientMod
{
public:
    GeeJoan::ModTypeEnum mod_type() override
    {
        // 和服务端的相同即可
        return (GeeJoan::ModTypeEnum) YourModTypeEnum::ModType_EchoMod;
    }

    void procMessage(std::unique_ptr<GeeJoan::ResposeDataPackage> hander) override
    {
        std::cout << " your rep : " << std::endl
                  << " modtype = " << int(hander->modtype) << std::endl
                  << " subtype = " << int(hander->subtype) << std::endl
                  << " ctaskid = " << int(hander->ctaskid) << std::endl
                  << " code    = " << int(hander->code) << std::endl
                  << " len     = " << int(hander->len) << std::endl
                  << "     msg = " << hander->message << std::endl;

    }
};


#include "ClientService.h"

using namespace GeeJoan;

int main(int argc, char *argv[])
{

    try
    {
        if (argc != 3)
        {
            std::cerr << "Usage: chat_client <host> <port>\n";
            return 1;
        }
        std::cout << " init " << std::endl;
        boost::asio::io_context io_context;

        ClientService c(io_context);

        // 注册模块
        c.registerModFunc(new EchoClientMod);

        c.setServeHost(argv[1]);
        c.setPort(argv[2]);

        c.connect_success_callback = [&]()
        {
            std::this_thread::sleep_for(std::chrono::seconds(1));
            std::cout << " connect success " << std::endl;
        };
        c.init();
        std::cout << " start " << std::endl;
        std::thread t([&io_context]()
                      {
                          std::cout << " start run " << std::endl;
                          io_context.run();
                          std::cout << "end " << std::endl;
                      });
        ClientService *client = &c;
        std::thread t2([&]()
                       {
                           std::string inpucmd;
                           std::cout << " input `i` send data , `q` exit " << std::endl;
                           std::cout << ">>>" << std::flush;
                           while (true)
                           {
                               std::cin.clear();
                               inpucmd.clear();
                               std::cin >> inpucmd;
                               if (inpucmd == "q")
                               {
                                   client->close();
                                   io_context.stop();
                                   break;
                               } else if (inpucmd.substr(0, 1) == "i")
                               {

                                   std::string senddata  ;
                                   std::cout << " input data :" << std::flush;
                                   std::cin >> senddata;
                                   auto sendStatusCallback = [](int status)
                                   {
                                       std::cout << " send status = " << status << std::endl;
                                   };
                                   c.send(YourModTypeEnum::ModType_EchoMod, 0, senddata, sendStatusCallback);
                               } else if (inpucmd.substr(0, 1) == "t")
                               {
                                   char a[4096] = {'a'};
                                   std::memset(a , 'a' , 4096);
                                   a[0]='c';
                                   a[1]='d';
                                   a[2]='e';
                                   a[3]='f';
                                   a[4095]='z';
                                   a[4094]='y';
                                   a[4093]='x';
                                   std::string senddata =a;
//                                   std::cout << " input data :" << std::flush;
//                                   std::cin >> senddata;
                                   auto sendStatusCallback = [](int status)
                                   {
                                       std::cout << " send status = " << status << std::endl;
                                   };
                                   c.send(YourModTypeEnum::ModType_EchoMod, 0, senddata, sendStatusCallback);
                               } else
                               {
                                   std::cerr << " unknow command" << std::endl;
                               }
                               std::cout << ">>>" << std::flush;
                           }
                       });
        t2.join();
        t.join();
    }
    catch (std::exception &e)
    {
        std::cerr << "Exception: " << e.what() << "\n";
    }

    return 0;
}